<?php
declare(strict_types=1);

namespace app\http\controller;

use app\api\model\User;
use GatewayWorker\Lib\Gateway;
use think\facade\Cache;
use think\facade\Env;
use think\facade\Log;
use Workerman\Lib\Timer;
use think\facade\Db;

class Bag
{
    public static $queueRoom = 'queue_room_';
    private static $freeRoom = 'free_room_';
    public static $global_room_activity_set = 'global_room_activity';
    public static $global_room_set = 'global_room_set_';
    private static $buy_expire_time = 90;
    public static $activity_push_prefix = 'activity_';
    public static $activity_uid_push_prefix = 'activity_uid_';

    public static $activity_room_uid_total = 'activity_room_uid_total';



    //进入页面
    public function enterPage($message,$client_id){
        $flag = $this->authLogin($message,$client_id);
        if($flag){
            $uid = $message['data']['uid'];
            $activity_id = $message['data']['activity_id'];
            //判断是否多端登录
            $is_uid_online = Gateway::isUidOnline($uid);
            $is_more_login = 0;
            if($is_uid_online){
                $is_more_login = 1;
            }
            //绑定client_id到UID上
            Gateway::bindUid($client_id, $uid);
            $uid_queue_list  = Cache::store('redis')->lrange(self::$queueRoom.$activity_id,0,-1);

            //加入活动房间
            Gateway::joinGroup($client_id,self::$activity_push_prefix.$activity_id);
            //加入用户多端房间
            $uid_room = self::$activity_uid_push_prefix.$activity_id.'_'.$uid;
            Gateway::joinGroup($client_id,$uid_room);

            //加入活动房间（uid加入）---统计人数用的
            Gateway::joinGroup($client_id,self::$activity_room_uid_total.$activity_id);


            //初始化参数
            $rank = $deadline_time = 0;
            $progress = 1;
            if(!empty($uid_queue_list) && in_array($uid,$uid_queue_list)){
                $find = array_search($uid,$uid_queue_list);
                if($find == 0){
                    $progress = 3;
                    $uid_info_key = $activity_id .'_'.$uid;
                    $uid_info = Cache::store('redis')->hgetall($uid_info_key);
                    $deadline_time = $uid_info['deadline_time'] ?? (time() + self::$buy_expire_time);
                    if($deadline_time < time()){
                        $deadline_time = time() + self::$buy_expire_time;
                    }
                }else{
                    $progress = 2;
                    $rank = $find;
                }
            }
            $last_users_info = [];
            if(in_array($progress,[1,2])){
                if($progress == 1){
                    $last_uids = array_slice($uid_queue_list,0,3);
                }else{
                    $last_uids = array_slice($uid_queue_list,0,3);
                    $last_uids = delByValue($last_uids,$uid);
                }
                $last_users_info = self::getBatchUserInfo($last_uids,$rank);
            }
            $to_message = [
                'type' => 'onLine',
                'data' => [
                    'uid' => $uid,
                    'activity_id' => $activity_id,
                    'sub_message' => '登录成功',
                    'is_more_login' => $is_more_login,   //是否多端登录
                    'queue_info' => [
                        'progress' => $progress,
                        'now' => time(),
                        'deadline_time' => intval($deadline_time),
                        'rank' => $rank,
                        'now_format' => date('Y-m-d H:i:s',time()),
                        'deadline_time_format' => ($deadline_time > 0) ? date('Y-m-d H:i:s',intval($deadline_time)) : 0,
                        'last_users_info' => $last_users_info,
                    ],
                ],
            ];
            Gateway::sendToGroup($uid_room,json_encode($to_message,JSON_UNESCAPED_UNICODE));

            //人数变化推送
            $all_uids = array_keys(Gateway::getUidListByGroup(self::$activity_room_uid_total.$activity_id));
            if(!empty($all_uids)){
                foreach ($all_uids as  $all_uid){
                    //每次过滤自己
                    $need_uids = delByValue($all_uids,$all_uid);
                    $user_list = self::getBatchUserInfo($need_uids);
                    $to_message = [
                        'type' => 'peopleChange',
                        'data' => [
                            'sub_message' => '活动人数变动',
                            'user_list' => $user_list,
                            'total_num' => Gateway::getUidCountByGroup(self::$activity_room_uid_total.$activity_id),
                        ],
                    ];
                    Gateway::sendToUid($all_uid,json_encode($to_message,JSON_UNESCAPED_UNICODE));
                }
            }
        }else{
            $to_message = [
                'type' => 'offLine',
                'data' => [
                    'client_id' => $client_id,
                    'sub_message' => '登录验证失败,强制下线'
                ],
            ];
            Gateway::closeClient($client_id,json_encode($to_message,JSON_UNESCAPED_UNICODE));
        }
    }

    //批量批量获取用户信息
    public static function getBatchUserInfo($uids , $rank = 3): array
    {
        if(empty($uids)) return [];
        $last_users_info = [];
        foreach ($uids as $last_uid){
            $user_info = User::detail($last_uid,['avatar']);
            $user_info = $user_info->toArray();
            $user_info['avatar_url'] = str_replace('http://localhost',Env::get('app.host_url'),$user_info['avatar_url']);
            $last_users_info[] = [
                'nick_name' => $user_info['nick_name'] ?? '',
                'avatar_url' => $user_info['avatar_url'] ?? '',
                'uid' => $user_info['user_id']
            ];
        }
        return array_slice($last_users_info,0,$rank);
    }


    //空队列情况处理
    public function emptyQueueDeal($activity_id,$uid,$client_id): array
    {
        $uid_info_key = $activity_id .'_'.$uid;
        $uid_info = Cache::store('redis')->hgetall($uid_info_key);
        $progress = 3;
        $now = time();
        if(!empty($uid_info['deadline_time']) && $now < $uid_info['deadline_time']){
            $deadline_time = $uid_info['deadline_time'] ;
        }else {
            $deadline_time = $now + self::$buy_expire_time;
            Cache::store('redis')->hmset($uid_info_key, ['deadline_time' => $deadline_time]);
            //延时处理
            $this->disQualification($activity_id, $uid, $client_id);
        }
        //加入队列
        Cache::store('redis')->rpush(self::$queueRoom.$activity_id,$uid);
        return [
            'now' => $now,
            'deadline_time' => $deadline_time,
            'progress' => $progress,
            'rank' => $rank ?? 0,
            'now_format' => date('Y-m-d H:i:s',$now),
            'deadline_time_format' => date('Y-m-d H:i:s',$deadline_time),
        ];
    }


    //非空队列处理
    public function nonEmptyQueueDeal($activity_id,$uid): array
    {
        $uid_list_free_key = self::$freeRoom.$activity_id;
        $uid_list_free = Cache::store('redis')->smembers($uid_list_free_key);

        $uid_info_key = $activity_id .'_'.$uid;
        $uid_info = Cache::store('redis')->hgetall($uid_info_key);


        $uid_queue_list  = Cache::store('redis')->lrange(self::$queueRoom.$activity_id,0,-1);
        echo '非空队列,对列是：'.json_encode($uid_queue_list).PHP_EOL;
        if(in_array($uid,$uid_queue_list)){
          $find = array_search($uid,$uid_queue_list);
          if($find == 0){
              $progress = 3;
              $deadline_time = $uid_info['deadline_time'] ?? (time() + self::$buy_expire_time);
              if($deadline_time <= time()){
                    $deadline_time = time() + self::$buy_expire_time;
              }
          }else{
              $progress = 2;
              $rank = $find;
          }
        }else{
            //不在队列中
            echo '我不在队列中';
            if(!in_array($uid,$uid_list_free)){
                echo '我不在在空置队列了,重新排队'.PHP_EOL;
                Cache::store('redis')->rpush(self::$queueRoom.$activity_id,$uid);
                $rank = Cache::store('redis')->llen(self::$queueRoom.$activity_id) -1 ;
                $progress = 2;

            }else{
                echo '我还在空置队列，继续保持中置状态'.PHP_EOL;
                $progress = 1;
            }
        }
        if(!empty($deadline_time)){
            $deadline_time_format = date('Y-m-d H:i:s',intval($deadline_time));
        }
        return [
            'now' => time(),
            'progress' => $progress,
            'rank' => $rank ?? 0,
            'deadline_time' => $deadline_time ?? 0,
            'now_format' => date('Y-m-d H:i:s') ,
            'deadline_time_format' => $deadline_time_format ?? '',
        ];
    }


    //断开用户其他活动的连接
    public function disOtherConnect($activity_id,$uid){
        //用户退出其他活动集合并发消息(全状态下)
        $this->unJoinGlobalSET($activity_id,$uid);
        //用户退出其他队列
        $this->unJoinGlobalActivitySET($activity_id,$uid);

    }

    //用户退出其他活动全球集合（进入活动就算的集合）
    public function unJoinGlobalSET($activity_id,$uid){
        echo '用户退出全球集合(全状态下)'.PHP_EOL;
        $total_set_list = Cache::store('redis')->SMEMBERS(self::$global_room_set);
        echo '所有全球集合（全状态下）：'.json_encode($total_set_list).PHP_EOL;
        $need = '';
        if(!empty($total_set_list)){
            $uid_key = $activity_id.'_'.$uid;
            foreach ($total_set_list as $val){
                //过滤当前活动
                if($val != $uid_key){
                    $rem = explode('_',$val);
                    if(in_array($uid,$rem)){
                        $need = $val;
                    }
                }
            }
        }
        if($need){
            echo '用户所在其他队列缓存：'.$need.PHP_EOL;
            Cache::store('redis')->SREM(self::$global_room_set,$activity_id.'_'.$uid);
            $other_sem = explode('_',$need);
            $other_activity_id = $other_sem[0];
            $to_message = [
                'type' => 'leave_activity',
                'data' => [
                    'activity_id' => $other_activity_id,
                    'uid' => $uid,
                    'sub_message' =>  '离开活动',
                ],
            ];
            $uid_room = self::$activity_uid_push_prefix.$other_activity_id.'_'.$uid;
            Gateway::sendToGroup($uid_room,json_encode($to_message,JSON_UNESCAPED_UNICODE));
        }


    }

    //退出用户其他队列
    public function unJoinGlobalActivitySET($activity_id,$uid){
        echo '用户退出全球活动集合'.PHP_EOL;
        $total_activity_set_list = Cache::store('redis')->SMEMBERS(self::$global_room_activity_set);
        echo '所有全球活动集合：'.json_encode($total_activity_set_list).PHP_EOL;
        $need = '';
        if(!empty($total_activity_set_list)){
            $uid_key = $activity_id.'_'.$uid;
            foreach ($total_activity_set_list as $val){
                //过滤当前活动
                if($val != $uid_key){
                    $rem = explode('_',$val);
                    if(in_array($uid,$rem)){
                        $need = $val;
                    }
                }
            }
        }
        if($need){
            Cache::store('redis')->SREM(self::$global_room_activity_set,$need);
            //同时删除用户之前的缓存信息
            $other_sem = explode('_',$need);
            $other_activity_id = $other_sem[0];
            echo '断开用户活动:'.$other_activity_id.'的连接'.PHP_EOL;


            //删除用户之前的队列
            $queue_room = self::$queueRoom.$other_activity_id;
            $other_queue_list = Cache::store('redis')->Lrange($queue_room,0,-1);

            if(in_array($uid,$other_queue_list)){
                echo '删除用户在其他活动的排队队列'.PHP_EOL;
                Cache::store('redis')->LREM($queue_room,$uid,1);

                //接着排在他后面的用户获奖
                echo '排在用户后面其他活动的用户开始获奖'.PHP_EOL;
                $new_queue_list = Cache::store('redis')->Lrange($queue_room,0,-1);
                if(!empty($new_queue_list)){
                    $winner = $new_queue_list[0];
                    $deadline_time = time() + self::$buy_expire_time;
                    $to_message = [
                        'type' => 'qualified',
                        'data' => [
                            'sub_message' =>  '恭喜，您已获取资格',
                            'now' =>  time(),
                            'deadline_time' => $deadline_time,
                            'now_format' => date('Y-m-d H:i:s',time()),
                            'deadline_time_format' => date('Y-m-d H:i:s',$deadline_time),
                            
                        ],
                    ];
                    $new_uid_room = self::$activity_uid_push_prefix.$other_activity_id.'_'.$winner;
                    Gateway::sendToGroup($new_uid_room,json_encode($to_message,JSON_UNESCAPED_UNICODE));

                    //同时更新缓存时间
                    Cache::store('redis')->hmset($other_activity_id.'_'.$winner,['deadline_time' => $deadline_time]);

                    //延时处理
                    $this->disQualification($other_activity_id,$winner);


                    //给后面的人发送排名变化
                    echo '给后面的人发送排名变化'.PHP_EOL;
                    array_shift($new_queue_list);
                    if(!empty($new_queue_list)){
                        foreach ($new_queue_list as $key => $queue_id){
                            $to_queue_message = [
                                'type' => 'queueChange',
                                'data' => [
                                    'uid' => $queue_id,
                                    'rank' => $key + 1,
                                    'sub_message' => '排名变化',
                                ],
                            ];
                            //更新排名
                            Gateway::sendToUid($queue_id,json_encode($to_queue_message));
                        }
                    }
                }
            }



            echo '给用户其他活动页面推送离开活动消息'.PHP_EOL;
            $to_message = [
                'type' => 'leave_activity',
                'data' => [
                    'activity_id' => $other_activity_id,
                    'sub_message' => '离开活动',
                ],
            ];
            $uid_room = self::$activity_uid_push_prefix.$other_activity_id.'_'.$uid;
            Gateway::sendToGroup($uid_room,json_encode($to_message,JSON_UNESCAPED_UNICODE));

            echo '删掉用户的截止时间缓存'.PHP_EOL;
            $uid_info_key = $other_activity_id .'_'.$uid;
            Cache::store('redis')->delete($uid_info_key);

            //同时删除用户其他活动的定时器
            $timer_key = 'Timer_'.$other_activity_id.'_'.$uid;
            $timer_ids = Cache::store('redis')->SMEMBERS($timer_key);
            echo '删掉用户其他活动的定时器：'.json_encode($timer_ids).PHP_EOL;
            if(!empty($timer_ids)){
                foreach ($timer_ids as $timer_id){
                    Timer::del($timer_id);
                }
            }
        }
    }



    //查看用户是是否在其他活动中存在队列
    public function hasJoinOtherQueue($activity_id,$uid): int
    {
        $global_room_key = self::$global_room_activity_set;
        $total_activity_set_list = Cache::store('redis')->SMEMBERS($global_room_key);
        $is_queue = 0;
        if(!empty($total_activity_set_list)){
            $uid_key = $activity_id.'_'.$uid;
            foreach ($total_activity_set_list as $val){
                //过滤当前活动
                if($val != $uid_key){
                    $rem = explode('_',$val);
                    if(in_array($uid,$rem)){
                        $is_queue = 1;
                    }
                }
            }
        }
        return $is_queue;
    }



    /**失去购买资格
     * @param $activity_id
     * @param $uid
     */
    public function disQualification($activity_id,$uid,$client_id = null){
        $time_id = Timer::add(self::$buy_expire_time, function () use($activity_id,$uid,$client_id) {
            // 用户加入活动闲置队列;
            $this->joinFreeQueue($activity_id,$uid);

            //将用户获奖截止时间置空
            $this->invalidWinnerDeadlineTime($activity_id,$uid);


            //排名变化处理;
            $this->queueLineChange($activity_id,$uid);
            $to_message = [
                'type' => 'qualified_expired',
                'data' => [
                    'uid' => $uid,
                    'client_id' => $client_id,
                    'activity_id' => $activity_id,
                    'sub_message' => '您已失去购买资格！',
                ],
            ];
            $uid_room = self::$activity_uid_push_prefix.$activity_id.'_'.$uid;
            Gateway::sendToGroup($uid_room,json_encode($to_message,JSON_UNESCAPED_UNICODE));


        }, [], false);

        //echo '定时器id是：'.$time_id.PHP_EOL;
        $timer_key = 'Timer_'.$activity_id.'_'.$uid;
        Cache::store('redis')->SADD($timer_key,$time_id);

    }



    //用户中奖截止时间失效
    public function invalidWinnerDeadlineTime($activity_id,$uid){
        $uid_info_key = $activity_id .'_'.$uid;
        Cache::store('redis')->hdel($uid_info_key,'deadline_time');

    }



    //在页面重新加入队列
    public function joinQueue($message,$client_id){
        $data = $message['data'];
        if(empty($data['uid'] || empty($data['activity_id']))){
            $to_message = [
                'type' => 'offLine',
                'data' => [
                    'client_id' => $client_id,
                    'sub_message' => '参数错误',
                ],
            ];
            sleep(1);
            //echo '参数错误';
            Gateway::closeClient($client_id,json_encode($to_message,JSON_UNESCAPED_UNICODE));
        }else{
            $uid_list_queue_key = self::$queueRoom.$data['activity_id'];
            $uid_list_queue = Cache::store('redis')->lrange($uid_list_queue_key,0,-1);

            if(empty($uid_list_queue)){
               // echo '重新加入队列是空队列情况下'.PHP_EOL;
                $res = $this->emptyQueueDeal($data['activity_id'],$data['uid'],$client_id);
            }else{
               // echo '重新加入队列是非空队列情况下'.PHP_EOL;
                $res = $this->nonEmptyQueueDeal($data['activity_id'],$data['uid']);
            }
            //断开其他活动连接初始化
            $this->disOtherConnect($data['activity_id'],$data['uid']);

            //加入全球队列（progress全状态）
            Cache::store('redis')->SADD(self::$global_room_set,$data['activity_id'].'_'.$data['uid']);

            if(in_array($res['progress'],[2,3])){
                Cache::store('redis')->SADD(self::$global_room_activity_set,$data['activity_id'].'_'.$data['uid']);
            }

            $last_users_info = [];
            if(in_array($res['progress'],[1,2])){
                if($res['progress'] == 1){
                    $last_uids = array_slice($uid_list_queue,0,3);
                }else{
                    $last_uids = array_slice($uid_list_queue,0,3);
                    foreach ($last_uids as $k => $last_uid){
                        if($last_uid == $data['uid']){
                            //如果包含在其中，则删除
                            unset($last_uids[$k]);
                        }
                    }
                }
                $last_users_info = self::getBatchUserInfo($last_uids,$res['rank']);
            }

            if($res['progress'] == 1){
                echo '中置状态 --- 再次主动加入队列'.PHP_EOL;
                Cache::store('redis')->rpush($uid_list_queue_key,$data['uid']);
                $rank = Cache::store('redis')->llen($uid_list_queue_key);
                $to_message = [
                    'type' => 'queue',
                    'data' => [
                        'client_id' => $client_id,
                        'rank' => $rank - 1,
                        'sub_message' => '排名',
                        'last_users_info' => $last_users_info,
                    ],
                ];
            }elseif($res['progress'] == 2){
                //队列状态
                $to_message = [
                    'type' => 'queue',
                    'data' => [
                        'client_id' => $client_id,
                        'rank' => $res['rank'],
                        'sub_message' => '排名',
                        'last_users_info' => $last_users_info,
                    ],
                ];
            }else{
                //获奖状态
                $to_message = [
                    'type' => 'qualified',
                    'data' => [
                        'client_id' => $client_id,
                        'activity_id' => $data['activity_id'],
                        'sub_message' => '恭喜，您已获取资格',
                        'now' => $res['now'],
                        'deadline_time' => $res['deadline_time'],
                        'now_format' => $res['now_format'] ,
                        'deadline_time_format' => $res['deadline_time_format'],

                    ],
                ];
            }
            $uid_room = self::$activity_uid_push_prefix.$data['activity_id'].'_'.$data['uid'];
            Gateway::sendToGroup($uid_room,json_encode($to_message,JSON_UNESCAPED_UNICODE));
        }
    }


    //用户主动离开空置状态
    public function leaveFreeRoom($message,$client_id){
        $data = $message['data'] ?? '';
        if(empty($data['uid']) || empty($data['activity_id'])){
            $to_message = [
                'type' => 'offLine',
                'data' => [
                    'client_id' => $client_id,
                    'sub_message' => '参数错误',
                ],
            ];
            sleep(1);
            //echo '参数错误';
            Gateway::closeClient($client_id,json_encode($to_message,JSON_UNESCAPED_UNICODE));
        }else{
            //离开空置状态
            echo '我离开了空置状态'.PHP_EOL;
            Cache::store('redis')->SREM(self::$freeRoom.$data['activity_id'],$data['uid']);

            //人数变化推送
            $all_uids = array_keys(Gateway::getUidListByGroup(self::$activity_room_uid_total.$data['activity_id']));
           // $all_uids = delByValue($all_uids,$data['uid']);
            // $to_message = [
            //     'type' => 'peopleChange',
            //     'data' => [
            //         'sub_message' => '活动人数变动',
            //         'user_list' => self::getBatchUserInfo($all_uids),
            //         'total_num' => Gateway::getUidCountByGroup(self::$activity_room_uid_total.$data['activity_id']),
            //     ],
            // ];
            // Gateway::sendToGroup(self::$activity_push_prefix.$data['activity_id'],json_encode($to_message,JSON_UNESCAPED_UNICODE));
            if(!empty($all_uids)){
                foreach ($all_uids as  $all_uid){
                   //每次过滤自己
                    $need_uids = delByValue($all_uids,$all_uid);
                    $user_list = self::getBatchUserInfo($need_uids);
                    $to_message = [
                        'type' => 'peopleChange',
                        'data' => [
                            'sub_message' => '活动人数变动',
                            'user_list' => $user_list,
                            'total_num' => Gateway::getUidCountByGroup(self::$activity_room_uid_total.$data['activity_id']),
                        ],
                    ];
                    Gateway::sendToUid($all_uid,json_encode($to_message,JSON_UNESCAPED_UNICODE));
                }
            }
        }
    }


    //推送已购买福袋商品
    public function pushOffSaleNotice($data): bool
    {
        try {
            Gateway::$registerAddress = Env::get('workerman.registerAddress');
            Log::channel('workman')->info('开始推送售卖信息');
            $to_message = [
                'type' => 'offSale',
                'data' => [
                    'off_sale' => $data['off_sale'],
                    'sub_message' => '已卖编号',
                    'activity_id' => $data['activity_id'],
                    'stock' => $data['stock']
                ],
            ];
            $activity_room = self::$activity_push_prefix.$data['activity_id'];
            Gateway::sendToGroup($activity_room,json_encode($to_message,JSON_UNESCAPED_UNICODE));
            return true;
        }catch (\Exception $e){
            Log::channel('workman')->info('推送售卖信息失败：'.$e);
            return false;
        }

    }


    //验证
    public function authLogin($message,$client_id): bool
    {
        $data = $message['data'];
        if(!empty($data['uid']) && !empty($data['activity_id']) && !empty($data['access_token'])){
            $current_userid = $this->getUserIdByAccessToken($data['access_token']);
            if(!$current_userid || $current_userid != $data['uid']){
                $to_message = [
                    'type' => 'offLine',
                    'data' => [
                        'client_id' => $client_id,
                        'sub_message' => '登录验证失败,强制下线(原因：冒名登录+token过期)'
                    ],
                ];
                Gateway::closeClient($client_id,json_encode($to_message,JSON_UNESCAPED_UNICODE));
                return  false;
            }else{
                return true;
            }
        }else{
            $to_message = [
                'type' => 'offLine',
                'data' => [
                    'client_id' => $client_id,
                    'sub_message' => '登录验证失败,强制下线'
                ],
            ];
            Gateway::closeClient($client_id,json_encode($to_message,JSON_UNESCAPED_UNICODE));
            return  false;
        }
    }


    /**
     * 根据token获取用户信息
     */
    public function getUserIdByAccessToken($token){
        $res = Cache::get($token);
        $user_id = '';
        if(!empty($res['user'])){
            $user_id = $res['user']['user_id'] ?? '';
        }

        return $user_id;
    }


    //验证福袋活动时间
    public function authBagActivity($data,$client_id){
        $activity_id = $data['activity_id'];
        $bag_info = $this->getBagInfo($activity_id,$client_id);
        if(time() > $bag_info['end_time']){
            $client_ids = Gateway::getClientIdByUid($data['uid']);
            if(!empty($client_ids)){
                foreach ($client_ids as $val){
                    $to_message = [
                        'type' => 'offLine',
                        'data' => [
                            'client_id' => $client_id,
                            'sub_message' => '活动已结束'
                        ],
                    ];
                    Gateway::closeClient($val,json_encode($to_message,JSON_UNESCAPED_UNICODE));
                }
            }
        }

    }

   //获取福袋活动信息
    public function getBagInfo($activity_id,$client_id){
        $bag_info = Db::table('toy_lucky_bag_activity')
            ->where('activity_id',$activity_id)
            ->find();
        if(empty($bag_info)){
            Gateway::closeClient($client_id);
        }
        return $bag_info;
    }



    //用户加入闲置队列
    public function joinFreeQueue($activity_id,$uid){
        $key = self::$freeRoom.'_'.$activity_id;
        Cache::store('redis')->sadd($key,$uid);
        //离开全球队列
        Cache::store('redis')->SREM(self::$global_room_activity_set,$activity_id.'_'.$uid);
        $to_message = [
            'type' => 'leave_queue',
            'data' => [
                'uid' => $uid,
                'activity_id' => $activity_id,
                'sub_message' => '您已离开队列'
            ],
        ];
        Gateway::sendToUid($uid,json_encode($to_message,JSON_UNESCAPED_UNICODE));
    }



    //用户自动下线
     public function closeConnect($client_id){
        $to_message = [
            'type' => 'offLine',
            'data' => [
                'client_id' => $client_id,
                'sub_message' => '下线'
            ],
        ];
        Gateway::closeClient($client_id,json_encode($to_message,JSON_UNESCAPED_UNICODE));
     }


     //用户排名变化
    public function queueLineChange($activity_id,$uid){
        $uid_list_queue_key = self::$queueRoom.$activity_id;
        $user_redis_key = $activity_id.'_'.$uid;
        $uid_queue_list  = Cache::store('redis')->lrange($uid_list_queue_key,0,-1);
        echo '排名发生变化'.PHP_EOL;
        if(!empty($uid_queue_list)){
            $old_winner = Cache::store('redis')->lpop($uid_list_queue_key);
            echo '原有中奖者出队列:'.$old_winner.PHP_EOL;
            $new_queue_list = Cache::store('redis')->lrange($uid_list_queue_key,0,-1);
            echo '剩余的队列成员：'.json_encode($new_queue_list).PHP_EOL;
            if(!empty($new_queue_list)){
                $winner = $new_queue_list[0];
                echo '排在第一位的即为中间者:'.$winner.PHP_EOL;

                $deadline_time = time() + self::$buy_expire_time;
                $to_message = [
                    'type' => 'qualified',
                    'data' => [
                        'uid' => $winner,
                        'activity_id' => $activity_id,
                        'sub_message' => '恭喜，您已获取资格',
                        'now' => time(),
                        'deadline_time' => $deadline_time,
                        'now_format' => date('Y-m-d H:i:s',time()) ,
                        'deadline_time_format' => date('Y-m-d H:i:s',$deadline_time),

                    ],
                ];
                echo '排在第一位赢家开始发送消息:'.PHP_EOL;
                Gateway::sendToUid($winner,json_encode($to_message,JSON_UNESCAPED_UNICODE));
                echo '排在第一位赢家开始发送消息结束'.PHP_EOL;


                //同时更新缓存时间
                Cache::store('redis')->hmset($user_redis_key,['deadline_time' => $deadline_time]);

                //开始延时处理
                $uid_info_key = $activity_id .'_'.$winner;
                $deadline_time = time() + self::$buy_expire_time;
                Cache::store('redis')->hmset($uid_info_key,['deadline_time' => $deadline_time]);
                //延时处理
                $this->disQualification($activity_id,$winner);


                //给后面的人发送排名变化
                echo '给后面的人发送排名变化'.PHP_EOL;
                $tmp_new_queue_list = $new_queue_list;
                array_shift($new_queue_list);
                if(!empty($new_queue_list)){
                    foreach ($new_queue_list as $key => $queue_id){
                        //当前用户前面的三人
                        $last_uids = array_slice($tmp_new_queue_list,0,3);
                        foreach ($last_uids as $k => $last_uid){
                            if($last_uid == $queue_id){
                                //如果包含在其中，则删除
                                unset($last_uids[$k]);
                            }
                        }
                        $rank = $key + 1;
                        $last_users_info = self::getBatchUserInfo($last_uids,$rank);
                        $to_queue_message = [
                            'type' => 'queueChange',
                            'data' => [
                                'uid' => $queue_id,
                                'rank' => $rank,
                                'sub_message' => '排名变化',
                                'last_users_info' => $last_users_info,
                            ],
                        ];
                        //更新排名
                        Cache::store('redis')->hmset($user_redis_key,['rank' => $key]);
                        Gateway::sendToUid($queue_id,json_encode($to_queue_message));
                    }
                }
            }
        }
    }


    //心跳检测
    public function pong($client_id){
        $message = [
            'type' => 'pong',
            'data' => [
                'client_id' => $client_id,
                'sub_message' => '我一直还在【心跳检测】'
            ],
        ];
        $message = json_encode($message,JSON_UNESCAPED_UNICODE);
        Gateway::sendToClient($client_id, $message);
    }

    //检验用户购买资格
    public function checkUserQualify($activity_id,$uid): bool
    {
        try {
            //判断socket是否连接
            // if(!Gateway::isUidOnline($uid)){
            //     Log::info("用户{$uid}不在线");
            //     return false;
            // }
            $uid_queue_list  = Cache::store('redis')->lrange(self::$queueRoom.$activity_id,0,-1);
            Log::channel("workman")->write("排队队列是：".json_encode($uid_queue_list));
            if(empty($uid_queue_list)) return false;
            if(!in_array($uid,$uid_queue_list) || $uid_queue_list[0] != $uid){
                echo "用户不在队列，没有购买资格";
                Log::channel("workman")->write("用户不在队列，没有购买资格");
                return  false;
            }
            return  true;
        }catch (\Exception $e){
            Log::channel("workman")->write($e->getMessage());
            return  false;
        }

    }

}